import {
  initChartStartX,
  initChartStartY,
  timeScaleHeight,
  unitWidth,
  barHeight,
  barMargin,
  todayOffset
} from "../config";
import {
  drawTimeScaleBackground,
  drawVerticalGridLines,
  drawHorizontalGridLines
} from "./time-scale";
import { drawTodayLine } from "./today";
import { drawTaskBars } from "./task-bar";
import { setupMouseMoveHandler } from "./mouse-interaction";


export class ChartRenderer {
  // ZRender实例
  private zr: any;
  // 任务数据
  private tasks: any;
  // 滚动位置
  private scrollState: ScrollState;
  // 是否是第一次处理
  private isFirstFlag: boolean;
  // 上一次处理移动
  private lastHandleMove: any;
  // 当前组
  private currentGroup: any;

  constructor(zr: any, tasks: any, scrollState: ScrollState) {
    this.zr = zr;
    this.tasks = tasks;
    this.scrollState = scrollState;
    this.isFirstFlag = true;
    this.lastHandleMove = null;
    this.currentGroup = null;
  }

  /**
   * 绘制图表
   * @param {boolean} clear 是否清空
   * @param {number} scrollX 滚动X
   * @param {number} scrollY 滚动Y
   */
  draw(clear = false, scrollX = this.scrollState.lastScrollX, scrollY = 0) {
    const isFirst = this.isFirstFlag;
    if (this.isFirstFlag) {
      this.isFirstFlag = false;
    }

    // 计算图表起始位置
    const chartState = this.calculateChartState(scrollX, scrollY);

    // 清空画布
    clear && this.zr.clear();

    // 设置鼠标移动处理
    this.setupMouseMoveHandler(chartState);

    // 绘制时间轴背景
    drawTimeScaleBackground(this.zr, chartState);

    // 绘制垂直网格线
    drawVerticalGridLines(
      this.zr,
      chartState,
      this.tasks,
      () => this.draw(false, scrollX, scrollY)
    );

    // 绘制水平网格线
    drawHorizontalGridLines(this.zr, chartState);

    // 绘制今天线
    drawTodayLine(
      this.zr,
      chartState.chartStartX,
      chartState.chartStartY,
      timeScaleHeight,
      barHeight,
      barMargin,
      todayOffset,
      this.tasks
    );

    // 绘制任务条
    const drawTaskBar = drawTaskBars(this.zr, this.tasks, chartState, this.draw.bind(this), this.currentGroup);

    // 如果屏幕里没有任务条，调整到第一个
    this.adjustScrollIfNoTasks(isFirst, drawTaskBar, chartState);
  }


  /**
   * 计算图表状态
   * @param {number} scrollX 滚动X
   * @param {number} scrollY 滚动Y
   * @returns {ChartState} 图表状态
   */
  calculateChartState(scrollX: number, scrollY: number): ChartState {
    const canvasWidth = this.zr.getWidth();
    const canvasHeight = this.zr.getHeight();

    // 计算图表起始位置
    const chartStartX = initChartStartX - scrollX;
    const chartStartY = Math.max(initChartStartY, timeScaleHeight) - scrollY;

    // 计算时间轴宽度
    const timeScaleWidth = Math.ceil(canvasWidth / unitWidth);

    return {
      chartStartX,
      chartStartY,
      canvasWidth,
      canvasHeight,
      timeScaleWidth,
      lastScrollX: scrollX,
      lastScrollY: scrollY
    };
  }

  /**
   * 设置鼠标移动处理
   * @param {Object} chartState 图表状态对象
   */
  setupMouseMoveHandler(chartState: ChartState) {
    this.lastHandleMove && this.zr.off('mousemove', this.lastHandleMove);
    this.lastHandleMove = setupMouseMoveHandler(this.zr, this.tasks, chartState, this.draw.bind(this), this.currentGroup);
    this.zr.on('mousemove', this.lastHandleMove);
  }

  /**
   * 如果没有任务条，调整滚动位置到第一个任务
   * @param {boolean} isFirst 是否首次绘制
   * @param {number} drawTaskBar 绘制的任务条数量
   * @param {Object} chartState 图表状态对象
   */
  adjustScrollIfNoTasks(isFirst: boolean, drawTaskBar: number, chartState: ChartState) {
    if (isFirst && drawTaskBar === 0) {
      if (this.tasks.length > 0) {
        console.log(this.tasks[0].start);
        const boundingLeft = Math.floor(chartState.lastScrollX / unitWidth);
        this.scrollState.lastScrollX += (this.tasks[0].start - boundingLeft - 1) * unitWidth;
        // 避免无限递归，直接重新计算并绘制
        const newChartState = this.calculateChartState(this.scrollState.lastScrollX, 0);
        this.zr.clear();
        // this.setupMouseMoveHandler(newChartState);
        drawTimeScaleBackground(this.zr, newChartState);
        drawVerticalGridLines(this.zr, newChartState, this.tasks, this.draw.bind(this));
        drawHorizontalGridLines(this.zr, newChartState);
        drawTodayLine(this.zr, newChartState.chartStartX, newChartState.chartStartY, timeScaleHeight, barHeight, barMargin, todayOffset, this.tasks);
        drawTaskBars(this.zr, this.tasks, newChartState, this.draw.bind(this), this.currentGroup);
      }
    }
  }

  /**
   * 设置当前操作组
   * @param {Object} group 操作组
   */
  setCurrentGroup(group: any) {
    this.currentGroup = group;
  }
}